﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.IO;
using JSON;
using System.Configuration;

namespace Facebook_Graph_Toolkit.Helpers {
    /// <summary>
    /// Helper functions related to connecting to Facebook's server
    /// </summary>
    public class WebResponseHelper {
        /// <summary>
        /// Gets the JSON Object which represents the Facebook Graph Api Object. Not for connections.
        /// </summary>
        /// <param name="ID">Facebook ID</param>
        /// <param name="AccessToken">Graph Api Access Token</param>
        /// <returns></returns>
        public static JsonObject GetJsonFromFacebookObject(string ID, string AccessToken) {
            string url = string.Format("https://graph.facebook.com/{0}?access_token={1}", ID, AccessToken);
            string response_string = GetWebResponse(url);
            if (response_string == "false") throw new FacebookException("Graph Api object does not exist.");
            return new JsonObject(response_string);
        }
        /// <summary>
        /// Gets a string from a url without caching
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        internal static string GetWebResponse(string url) {
            string StringResponse;
            using (WebResponse objResponse = GetWebResponseObject(url)) {
                using (StreamReader sr = new StreamReader(objResponse.GetResponseStream())) {
                    StringResponse = sr.ReadToEnd();
                }
            }
            return StringResponse;
        }
        internal static WebResponse GetWebResponseObject(string url) {
            string RequestURL = url;
            WebRequest Request = HttpWebRequest.Create(RequestURL);
            Request.Timeout = 5000;
            FacebookGraphToolkitConfiguration Config = Common.GetAppConfig(false);
            if(Config!=null) if (Config._webtimeout != 0) Request.Timeout = Config._webtimeout;
            try {
                return Request.GetResponse();
            }
            catch (WebException WebEx) {
                if (WebEx.Status == WebExceptionStatus.ProtocolError) {
                    HttpWebResponse ErrorResponse = (HttpWebResponse)WebEx.Response;
                    if (ErrorResponse.StatusCode != HttpStatusCode.BadRequest) throw WebEx;
                    string ErrorType = "";
                    string ErrorMessage = "";
                    using (StreamReader sr = new StreamReader(ErrorResponse.GetResponseStream())) {
                        JsonObject ErrorJO = new JsonObject(sr.ReadToEnd());
                        ErrorType = (string)((JsonObject)ErrorJO["error"])["type"];
                        ErrorMessage = (string)((JsonObject)ErrorJO["error"])["message"];
                        sr.Close();
                    }
                    ErrorResponse.Close();
                    throw new FacebookException(string.Format("{0} : {1}", ErrorType, ErrorMessage));
                } else throw;
            }
        }
        internal static string UploadString(string address, string data) {
            WebClient client = new WebClient();
            string response = "";
            try {
                response = client.UploadString(address, data);
            }
            catch (WebException WebEx) {
                if (WebEx.Status == WebExceptionStatus.ProtocolError) {
                    HttpWebResponse ErrorResponse = (HttpWebResponse)WebEx.Response;
                    if (ErrorResponse.StatusCode != HttpStatusCode.BadRequest) throw WebEx;
                    string ErrorType = "";
                    string ErrorMessage = "";
                    using (StreamReader sr = new StreamReader(ErrorResponse.GetResponseStream())) {
                        JsonObject ErrorJO = new JsonObject(sr.ReadToEnd());
                        ErrorType = (string)((JsonObject)ErrorJO["error"])["type"];
                        ErrorMessage = (string)((JsonObject)ErrorJO["error"])["message"];
                        sr.Close();
                    }
                    throw new FacebookException(string.Format("{0} : {1}", ErrorType, ErrorMessage));
                } else throw;
            }
            finally {
                client.Dispose();
            }
            return response;
        }
        internal static string GetWebResponseRedirectURL(string url) {
            WebResponse objResponse = GetWebResponseObject(url);
            return objResponse.ResponseUri.ToString();
        }
    }
}